package com.ruoyi.common.utils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.http.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 地理位置工具类
 * 
 * @author ruoyi
 */
public class GeoUtils {
    private static final Logger log = LoggerFactory.getLogger(GeoUtils.class);
    
    // 高德地图API的接口地址
    private static final String AMAP_GEO_URL = "https://restapi.amap.com/v3/geocode/geo";
    
    // 百度地图API的接口地址
    private static final String BAIDU_GEO_URL = "https://api.map.baidu.com/geocoding/v3/";
    
    // 天地图API的接口地址
    private static final String TIANDITU_GEO_URL = "http://api.tianditu.gov.cn/geocoder";
    
    // 腾讯地图API的接口地址
    private static final String TENCENT_GEO_URL = "https://apis.map.qq.com/ws/geocoder/v1/";
    
    // 高德地图API密钥
    private static String key = "";

    public static void setKey(String key) {
        GeoUtils.key = key;
    }

    public static String getKey() {
        return key;
    }

    /**
     * 使用高德地图API根据地址获取经纬度
     *
     * @param address 地址
     * @return 包含经纬度信息的数组，格式为 [经度, 纬度]，若获取失败则返回null
     */
    public static String[] getLocationByAddressFromAMap(String address) {
        if (StringUtils.isEmpty(address)) {
            return null;
        }
        
        String key = getKey();
        if (StringUtils.isEmpty(key)) {
            log.error("高德地图API密钥未配置");
            return null;
        }
        
        try {
            String param = "address=" + address + "&key=" + key + "&output=json";
            String result = HttpUtils.sendGet(AMAP_GEO_URL, param);
            
            if (StringUtils.isEmpty(result)) {
                log.error("获取地址经纬度失败，地址：{}", address);
                return null;
            }
            
            JSONObject json = JSON.parseObject(result);
            
            if (json.getInteger("status") != 1) {
                log.error("获取地址经纬度失败，地址：{}，原因：{}", address, json.getString("info"));
                return null;
            }
            
            if (json.getJSONArray("geocodes").isEmpty()) {
                log.error("未找到该地址对应的经纬度，地址：{}", address);
                return null;
            }
            
            String location = json.getJSONArray("geocodes").getJSONObject(0).getString("location");
            if (StringUtils.isEmpty(location)) {
                return null;
            }
            
            return location.split(",");
        } catch (Exception e) {
            log.error("获取地址经纬度异常，地址：{}", address, e);
            return null;
        }
    }
    
    /**
     * 使用百度地图API根据地址获取经纬度
     *
     * @param address 地址
     * @return 包含经纬度信息的数组，格式为 [经度, 纬度]，若获取失败则返回null
     */
    public static String[] getLocationByAddressFromBaidu(String address) {
        if (StringUtils.isEmpty(address)) {
            return null;
        }

        String key = getKey();
        if (StringUtils.isEmpty(key)) {
            log.error("百度地图API密钥未配置");
            return null;
        }
        
        try {
            String param = "address=" + address + "&ak=" + key + "&output=json";
            String result = HttpUtils.sendGet(BAIDU_GEO_URL, param);
            
            if (StringUtils.isEmpty(result)) {
                log.error("获取地址经纬度失败，地址：{}", address);
                return null;
            }
            
            JSONObject json = JSON.parseObject(result);
            
            if (json.getInteger("status") != 0) {
                log.error("获取地址经纬度失败，地址：{}，原因：{}", address, json.getString("message"));
                return null;
            }
            
            JSONObject location = json.getJSONObject("result").getJSONObject("location");
            if (location == null) {
                log.error("未找到该地址对应的经纬度，地址：{}", address);
                return null;
            }
            
            String lng = location.getString("lng"); // 经度
            String lat = location.getString("lat"); // 纬度
            
            return new String[]{lng, lat};
        } catch (Exception e) {
            log.error("获取地址经纬度异常，地址：{}", address, e);
            return null;
        }
    }
    
    /**
     * 使用天地图API根据地址获取经纬度
     *
     * @param address 地址
     * @return 包含经纬度信息的数组，格式为 [经度, 纬度]，若获取失败则返回null
     */
    public static String[] getLocationByAddressFromTianditu(String address) {
        if (StringUtils.isEmpty(address)) {
            return null;
        }

        String key = getKey();
        if (StringUtils.isEmpty(key)) {
            log.error("天地图API密钥未配置");
            return null;
        }
        
        try {
            String param = "ds={\"keyWord\":\"" + address + "\"}&tk=" + key;
            String result = HttpUtils.sendGet(TIANDITU_GEO_URL, param);
            
            if (StringUtils.isEmpty(result)) {
                log.error("获取地址经纬度失败，地址：{}", address);
                return null;
            }
            
            JSONObject json = JSON.parseObject(result);
            
            if (!"0".equals(json.getString("status"))) {
                log.error("获取地址经纬度失败，地址：{}，原因：{}", address, json.getString("msg"));
                return null;
            }
            
            JSONObject location = json.getJSONObject("location");
            if (location == null) {
                log.error("未找到该地址对应的经纬度，地址：{}", address);
                return null;
            }
            
            String lon = location.getString("lon"); // 经度
            String lat = location.getString("lat"); // 纬度
            
            return new String[]{lon, lat};
        } catch (Exception e) {
            log.error("获取地址经纬度异常，地址：{}", address, e);
            return null;
        }
    }
    
    /**
     * 使用腾讯地图API根据地址获取经纬度
     *
     * @param address 地址
     * @return 包含经纬度信息的数组，格式为 [经度, 纬度]，若获取失败则返回null
     */
    public static String[] getLocationByAddressFromTencent(String address) {
        if (StringUtils.isEmpty(address)) {
            return null;
        }

        String key = getKey();
        if (StringUtils.isEmpty(key)) {
            log.error("腾讯地图API密钥未配置");
            return null;
        }

        try {
            String param = "address=" + address + "&key=" + key;
            String result = HttpUtils.sendGet(TENCENT_GEO_URL, param);

            if (StringUtils.isEmpty(result)) {
                log.error("获取地址经纬度失败，地址：{}", address);
                return null;
            }

            JSONObject json = JSON.parseObject(result);

            if (json.getInteger("status") != 0) {
                log.error("获取地址经纬度失败，地址：{}，原因：{}", address, json.getString("message"));
                return null;
            }

            JSONObject location = json.getJSONObject("result").getJSONObject("location");
            if (location == null) {
                log.error("未找到该地址对应的经纬度，地址：{}", address);
                return null;
            }

            String lng = location.getString("lng"); // 经度
            String lat = location.getString("lat"); // 纬度

            return new String[]{lng, lat};
        } catch (Exception e) {
            log.error("获取地址经纬度异常，地址：{}", address, e);
            return null;
        }
    }
    
    /**
     * 根据地址获取经纬度（先尝试高德地图，失败后尝试百度地图，最后尝试天地图）
     *
     * @param address 地址
     * @return 包含经纬度信息的数组，格式为 [经度, 纬度]，若获取失败则返回null
     */
    public static String[] getLocationByAddress(String address) {

        return getLocationByAddressFromTencent(address);
    }
} 